package com.rtsapp.server.network.session;

import io.netty.channel.Channel;

import java.net.InetSocketAddress;

/**
 * Session 代表一个连接, 分客户端Session和服务器端Session, 该类的异常情况是重要的
 * Session是对Netty Channel的简单封装
 * 
 * 在Server端, Server维护着一批从客户端连接过来的Session
 * 在AysncClient端, AysncClient维护者一组连接到其他服务器的Session
 * 考虑两种情况:
 * 		1.游戏客户端直接连接服务器
 * 		  服务器的SessionId为该服务器内部唯一,远程Id为-1，表示客户端
 * 		2. 内部游戏服务器A，连接另外一台游戏服务器B
 * 			A：异步客户端A的RemoteId为另外一台服务器的Id
 * 			B：作为服务器，Session中的RemoteId为连接他的服务器的Id
 * 		
 * 		关于RemoteId，对于连接客户端来说知道知道RemoteId为多少, 但对于被动接收的服务器, 不知道remoteId为多少
 * 1. 连接状态:已连接, 断开连接, 关闭中
 * 2. 连接双方:远程地址, 本地地址 
 * 3. id: serverId所在服务器, sessionId该服务器内的会话id( 这样能定位到任何一台服务器的某一个连接 )
 * 4. 数据传递: 发送数据的接口
 * 5. 连接级别的属性绑定操作: setAttribute, getAttribute
 * @author admin
 *
 */
public interface Session {
	
	enum SessionType{
		ClientSession,
		ServerSession
	}
	
	
	/**
	 * session的类型
	 * @return 客户端类型的session，或者服务器端的session
	 */
	SessionType getType( );

	/**
	 * 获得Session对应的Netty
	 * @return
	 */
	Channel getChannel( );

	/**
	 * sessionMgr中的唯一sessionId, sessionId不能变
	 * @return
	 */
	long getSessionId( );
	
	/**
	 * 远端的身份id标识
	 * @return
	 */
	long getRemoteId( );
	
	
	/**
	 * 设置远端身份ID，一般只能设置一次
	 * @param remoteId
	 */
	void setRemoteId( long remoteId );
	
	
	/**
	 * 发送数据
	 * 线程安全
	 * @param message
	 */
	void send( Object message );


	/**
	 * 发送数据，发送完毕后，关闭连接
	 * @param message
	 */
	void sendAndClose( Object message );
	
	/**
	 * write发送数据，兼容老接口，世界是调用send
	 * 线程安全
	 * @param message
	 */
	void write( Object message );
	
	void flush( );
	/**
	 * 关闭Session
	 * 多次调用只执行一次调用
	 */
	void close();
	
	/**
	 * 存数据,线程安全
	 * @param key
	 * @param object
	 */
	void setAttribute( String key, Object object );
	
	/**
	 * 取数据, 线程安全
	 * @param key
	 * @return
	 */
	Object getAttribute( String key );
	
	
	void removeAttribute( String key );
	
	
	InetSocketAddress getRemoteAddress( );
	
	
	InetSocketAddress getLocalAddress();
	
}
